///////////////////////////////////////////////////////////////////////////////
//	FILENAME:	eTRTFDFileLink.h 
//	SUMMARY:	Implementation of an RTFD inclusion handler
//	SUPERCLASS:	eTFileLink:eTImage:Object
//	INTERFACE:	None
//	PROTOCOLS:	None added
//	AUTHOR:		Rohit Khare
//	COPYRIGHT:	(c) 1994 California Institure of Technology, eText Project
///////////////////////////////////////////////////////////////////////////////
//	IMPLEMENTATION COMMENTS
//		Okay: here are the facts of life about NeXT's lousy RTFD implementation
//	(trust me, I know, I know the Text object every which way except from the
//	inside... grrr). It goes: 
//		<space char>string<spacechar>\width<inTwips>\height<inTwips>\n}
//	(the string spec is such that you have to read it in two passes -- that's
//	why I always prefix a string by the length. (e.g. NeXT fails on a file
//	named "\width960"))
//		
//	OK, once you have the string, you have a relative filename component. Where
//	do we get the root filename component? We assume that we can reach out
//	and access() [[[view etDoc] docInfo] docPath]. 
//	
//	OK, now we have a fully-qualified absolute pathname. If it's a TIFF image,
//	we want to promote self to be an eTImage object encapsulating that file.
//	otherwise we want to be an eTFileLink.
//
//	THERE ARE NO eTRTFDFileLinks IN THE SYSTEM AFTER readRichText: !!!!
//		All such instances are "promoted" by redirecting their isa pointer
//	Thus, when the file is written out, RTFD-objects will be implicitly
//	promoted to first-class eText objects. 
//
//	As an exercise for the reader: With enough cojones, it should be possible
//	to write a generic mutator to eTImage-derived objects; just make sure that
//	this object has as many bytes of storage as the larget morph target. Then
//	you could _automatically_ morph a .snd inclusion into an eTAudio :)
///////////////////////////////////////////////////////////////////////////////
//	HISTORY
//	07/23/94:	Created. First actual implementation.
///////////////////////////////////////////////////////////////////////////////

#import "eTRTFDFileLink.h"

@implementation eTRTFDFileLink
+ toolAwake: theApp
{
	[theApp   registerAnnotation: [eTRTFDFileLink class] 
							name: "eTRTFDFileLink"
					RTFDirective: "NeXTGraphic"
					   menuLabel: NULL
						 menuKey: '\0'
						menuIcon: (NXImage *) nil];
	return self;
}
- readRichText:(NXStream *) stream forView:view
{
	const char *const * types;
	char *ext;
	NXAtom	localPath,rootPath;
	char	buffer[MAXPATHLEN],ch;
	int		height=0, width=0,i=0;
	char	*tmp;
	BOOL	foundImage=NO;
	
	// we first have to do this because this silly hack-class of ours can't
	// call [super readRichText:...] (this code is in eTImage.m)
	if (!etDoc || !theText) {
		theText = view;
		etDoc = [theText etDoc];
		[etDoc registerNotification:self];
	}
	// first fill in the buffer with all the characters up to and including \n
	while ((i < MAXPATHLEN) && ((ch = NXGetc(stream)) != '\n')) {
		buffer[i++] = ch;
	}
	buffer[i] = 0;	
	// now work backward to get height.
	tmp = rindex(buffer,'\\');
	if (tmp && !strncmp(tmp, "\\height",7)) {
		//we have a valid \height entry beginning at tmp
		sscanf(tmp+7,"%d",&height);
		// now nullify the \ so we can go backwards to \width
		*tmp = 0;
	}
	// now work backward to get width.
	tmp = rindex(buffer,'\\');
	if (tmp && !strncmp(tmp, "\\width",6)) {
		//we have a valid \height entry beginning at tmp
		sscanf(tmp+6,"%d",&width);
		// now nullify the \ so we can go backwards to the string
		*tmp = 0;
		// and also consume the space character separating string from \width
		*(tmp - 1) = 0;
	}
	
	// skip the leading space -- is there one?
	tmp = buffer;
	if (*tmp == ' ') tmp++;
	localPath = NXUniqueString(tmp);
	rootPath = [[[view etDoc] docInfo] docPath];
	sprintf(buffer, "%s/%s", rootPath, localPath);
	
	// OK, now what? We have valid data.
	//NXLogError("\\NeXTGraphic got \"%s\" h:%d w:%d in \"%s\"", 
	//			localPath, height, width, rootPath); 
		
	tmp = rindex(buffer,'/'); //get the extension of the basename.
	tmp = rindex(tmp,'.');
	if (tmp && *(++tmp)) {
		// ext is now a pointer to the extension of buffer, if there is one.
		ext = NXUniqueString(tmp); // ext of basename
		types = [NXImage imageFileTypes];
		for(i=0; (types[i] && !foundImage); i++)
			if (!strcmp(ext,types[i])) foundImage = YES;
	}
	if (foundImage) {
		// If the target file can be viewed as imageable data, we should
		// "morph" into an eTImage instance based on that file.
		// The code that eTImage would execute in this situation:
		//		1) create an imageComponent
		//		2) [self setImageComponent] 
		self->isa = [eTImage class]; // assumes that we are a subclass of it
		[self setImageComponent: [[[eTImageComponent alloc] 
				initInDoc:etDoc linked:NO]
				readComponentFromPath:buffer]];
	} else {
		// else we need to init etFileComponent _and_ attempt to initialize
		// eTImageComponent from buffer.tiff.
		self->isa = [eTFileLink class];
		
		etFileComponent = [[[eTComponent alloc] initInDoc:etDoc linked:NO]
							readComponentFromPath:buffer];
		strcat(buffer,".tiff"); //this is NeXT's default behavior
		[self setImageComponent: [[[eTImageComponent alloc] 
				initInDoc:etDoc linked:NO]
				readComponentFromPath:buffer]]	;
	}
	return self;
}
@end